package com.itheima.service.impl;
import com.alibaba.fastjson.JSON;
import com.itheima.pojo.Blog;
import com.itheima.pojo.BlogInfo;
import com.itheima.repository.ESManagerRepository;
import com.itheima.service.BlogService;
import com.itheima.service.ESManagerService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class ESManagerServiceImpl implements ESManagerService {

    @Autowired
    private ESManagerRepository esManagerRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Autowired
    private BlogService blogService;

    //创建索引库和映射
    @Override
    public void initElasticIndex() {
        //索引
        elasticsearchTemplate.createIndex(BlogInfo.class);
        //映射
        elasticsearchTemplate.putMapping(BlogInfo.class);
    }

    //导入所有数据
    @Override
    @Transactional
    public void importAll() {
        //获取所有数据
        List<Blog> blogList = blogService.getAll();
        //判断是否有数据
        if (blogList==null||blogList.size()<=0){
            throw new RuntimeException("当前没有数据被查询到,无法导入索引库");
        }
        //将List<Blog>转换为List<BlogInfo>
        String blogJson = JSON.toJSONString(blogList);
        List<BlogInfo> blogInfoList = JSON.parseArray(blogJson, BlogInfo.class);
        //保存数据到索引库
        esManagerRepository.saveAll(blogInfoList);
    }

    //根据id添加数据到索引
    @Override
    @Transactional
    public void importById(String uid) {
        //获取数据
        Blog blog = blogService.findById(uid);
        //判断是否有数据
        if (blog==null){
            throw new RuntimeException("当前没有数据被查询到,无法导入索引库");
        }
        //Blog转换为BlogInfo
        String blogStr = JSON.toJSONString(blog);
        BlogInfo blogInfo = JSON.parseObject(blogStr, BlogInfo.class);
        //保存数据到索引库
        esManagerRepository.save(blogInfo);
    }

    //通过uid删除ES中的数据
    @Override
    @Transactional
    public void deleteById(String uid) {
        esManagerRepository.deleteById(uid);
    }

    //通过uids删除ES中的数据
    @Override
    @Transactional
    public void deleteByIds(String uids) {
        String[] uIds = uids.split(",");
        for (String uId : uIds) {
            esManagerRepository.deleteById(uId);
        }
    }

    //通过ES搜索博客
    @Override
    public List<BlogInfo> findByKeywords(String keywords, Integer currentPage, Integer pageSize) {
        //构建搜索条件
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //根据文本内容匹配搜索
        boolQueryBuilder.should(QueryBuilders.queryStringQuery(keywords).defaultField("content"));

        //分页
        Pageable pageable= PageRequest.of(currentPage-1,pageSize);

        //构建查询
        SearchQuery query=new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withPageable(pageable)
                .build();
        Page<BlogInfo> blogInfoPage = esManagerRepository.search(query);

        return blogInfoPage.getContent();
    }

    //搜索Blog
    @Override
    public Page<BlogInfo> find2BlogByKeywords(String keywords, Integer currentPage, Integer pageSize) {
        //构建搜索条件
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //根据标题分类
        boolQueryBuilder.should(QueryBuilders.termQuery("title",keywords));
        //根据介绍分类
        boolQueryBuilder.should(QueryBuilders.termQuery("summary",keywords));
        //根据文本内容匹配搜索
        boolQueryBuilder.should(QueryBuilders.queryStringQuery(keywords).defaultField("content"));

        //分页
        Pageable pageable= PageRequest.of(currentPage-1,pageSize);

        //构建查询
        SearchQuery query=new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withPageable(pageable)
                .build();
        Page<BlogInfo> blogInfoPage = esManagerRepository.search(query);

        return blogInfoPage;
    }

    //根据标签获取相关的博客
    @Override
    public List<BlogInfo> findByTagUid(String tagUid, Integer currentPage, Integer pageSize) {
        //构建搜索条件
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //根据标签匹配搜索
        boolQueryBuilder.should(QueryBuilders.termQuery("tagUid",tagUid));

        //分页
        Pageable pageable= PageRequest.of(currentPage-1,pageSize);

        //构建查询
        SearchQuery query=new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withPageable(pageable)
                .build();
        Page<BlogInfo> blogInfoPage = esManagerRepository.search(query);

        return blogInfoPage.getContent();
    }

    @Override
    public List<BlogInfo> findByBlogSortUid(String blogSortUid, Integer currentPage, Integer pageSize) {
        //构建搜索条件
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //根据分类匹配搜索
        boolQueryBuilder.should(QueryBuilders.termQuery("blogSortUid",blogSortUid));

        //分页
        Pageable pageable= PageRequest.of(currentPage-1,pageSize);

        //构建查询
        SearchQuery query=new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withPageable(pageable)
                .build();
        Page<BlogInfo> blogInfoPage = esManagerRepository.search(query);

        return blogInfoPage.getContent();
    }

    //根据作者获取相关的博客
    @Override
    public List<BlogInfo> findByAuthor(String author, Integer currentPage, Integer pageSize) {
        //构建搜索条件
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //根据文本内容匹配搜索
        boolQueryBuilder.should(QueryBuilders.queryStringQuery(author).defaultField("author"));

        //分页
        Pageable pageable= PageRequest.of(currentPage-1,pageSize);

        //构建查询
        SearchQuery query=new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withPageable(pageable)
                .build();
        Page<BlogInfo> blogInfoPage = esManagerRepository.search(query);

        return blogInfoPage.getContent();
    }

}
